package org.cancan.demo.panel;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

public class VideoCaptureThread implements Runnable {
    private final CameraFrame frame;
    private volatile boolean running = true;
    private CascadeClassifier faceDetector;

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public VideoCaptureThread(CameraFrame frame) {
        this.frame = frame;
        // 加载人脸检测器
        faceDetector = new CascadeClassifier("D:\\OpenSources\\Opencv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_default.xml");
        if (faceDetector.empty()) {
            System.out.println("Error: Could not load face detector.");
        }
    }

    @Override
    public void run() {
        VideoCapture camera = new VideoCapture(0); // 0 is the default camera
        if (!camera.isOpened()) {
            System.out.println("Error: Could not open camera.");
            return;
        }

        while (running && !Thread.currentThread().isInterrupted()) {
            Mat mat = new Mat();
            if (camera.read(mat)) {
                // 进行人脸检测
                MatOfRect faceDetections = new MatOfRect();
                faceDetector.detectMultiScale(mat, faceDetections);

                // 在检测到的人脸上绘制矩形框
                for (Rect rect : faceDetections.toArray()) {
                    Imgproc.rectangle(mat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0), 3);
                }
                BufferedImage image = matToBufferedImage(mat);
                frame.setImage(image);
            }
        }

        camera.release();
    }

    private BufferedImage matToBufferedImage(Mat matrix) {
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode(".jpg", matrix, mob);
        byte[] byteArray = mob.toArray();
        InputStream in = new ByteArrayInputStream(byteArray);
        try {
            return ImageIO.read(in);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void stop() {
        running = false;
    }
}